﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Lidgren.Network;
using Networking.Packets;
using Microsoft.Xna.Framework;
using Lidgren.Network.Xna;

namespace Networking
{
    public class SimpleGameClient
    {
        string HOST = "localhost";
        int PORT = 14242;
        string NAME = "magicarena";

        NetClient Client;
        List<PlayerInfoPacket> _PlayerInfo = new List<PlayerInfoPacket>(2);
        List<LocationPacket> _Location = new List<LocationPacket>(5);

        public List<PlayerInfoPacket> PlayerInfoPackets
        {
            get { return _PlayerInfo; }
        }
        public List<LocationPacket> LocationPackets
        {
            get{return _Location;}
        }

        public SimpleGameClient()
        {
            LoadConfigFile();

            NetPeerConfiguration config = new NetPeerConfiguration("magicarena");
            
            Client = new NetClient(config);
            Client.Start();
        }

        private void LoadConfigFile()
        {
            System.IO.StreamReader file = new System.IO.StreamReader("network.conf");
            if (file == null)
            {
                Console.WriteLine("Could not find network.conf, using default values");
            }
            NAME = file.ReadLine();
            HOST = file.ReadLine();
            PORT = int.Parse(file.ReadLine());
            file.Close();
        }

        public void SendPlayer(UInt64 PlayerId, string displayName, int health=-1)
        {
            PlayerInfoPacket pack = new PlayerInfoPacket(PlayerId, displayName, health);
            NetOutgoingMessage msg = Client.CreateMessage();
            PlayerInfoPacket.BuildOutputMessage(ref msg, pack);
            Client.SendMessage(msg, NetDeliveryMethod.ReliableUnordered);
        }
        public void SendLocation(Vector3 location, UInt64 playerId)
        {
            SendLocation(location, new Quaternion(0,0,0,0), playerId);
        }
        public void SendLocation(Vector3 location, Quaternion rotation, UInt64 playerId)
        {
            LocationPacket pack = new LocationPacket(playerId, location, rotation);
            NetOutgoingMessage msg = Client.CreateMessage();
            LocationPacket.BuildOutputMessage(ref msg, pack);
            Client.SendMessage(msg, NetDeliveryMethod.UnreliableSequenced);
        }

        public void Update()
        {
            _PlayerInfo.Clear();
            _Location.Clear();
            NetIncomingMessage msg;
            // handle incoming message
            while ((msg = Client.ReadMessage()) != null)
            {
                switch (msg.MessageType)
                {
                    case NetIncomingMessageType.DebugMessage:
                    case NetIncomingMessageType.ErrorMessage:
                    case NetIncomingMessageType.WarningMessage:
                    case NetIncomingMessageType.VerboseDebugMessage:
                    case NetIncomingMessageType.StatusChanged:
                        string text = msg.ReadString();
                        Console.WriteLine(text);
                        break;
                    case NetIncomingMessageType.Data:
                        UInt64 TAG = (UInt64)msg.ReadUInt64();
                        switch (TAG)
                        {
                            case LocationPacket.TAG:
                                LocationPacket pack = new LocationPacket();
                                LocationPacket.ParseMessage(msg, ref pack);
                                _Location.Add(pack);
                                break;
                            case PlayerInfoPacket.TAG:
                                PlayerInfoPacket infopack = new PlayerInfoPacket();
                                PlayerInfoPacket.ParseMessage(msg, ref infopack);
                                _PlayerInfo.Add(infopack);
                                break;
                        }
                        break;
                    default:
                        Console.WriteLine("Unhandled type: " + msg.MessageType + " " + msg.LengthBytes + " bytes");
                        break;
                }
            }
        }

        public void Start()
        {
            Client.Connect(HOST, PORT);
        }

        public void Close()
        {
            Client.Disconnect("Requested By User");
        }
    }
}
